package com.skyworth.acreate_mybatis.util;

 
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.*;

import com.skyworth.util.PUtils;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;


// insert into resources_role(role_id,id) select '1',id from resources ;
public class ResourceConfigImport {

    private static Logger logger = LoggerFactory.getLogger(ResourceConfigImport.class);

    private final static String RESOURCE_FILE_PATH = "resouces-config-aps.xml";
//    private final static String RESOURCE_FILE_PATH = "resouces-config-mes.xml";
//    private final static String RESOURCE_FILE_PATH = "resouces-config-oms.xml";
//    private final static String RESOURCE_FILE_PATH = "resouces-config-fms.xml";
//    private final static String RESOURCE_FILE_PATH = "resouces-config-pms.xml";
//    private final static String RESOURCE_FILE_PATH = "resouces-config.xml";

    private final static Map<String, LinkedHashMap<String,String>> CACHE_MEMUS_SECURERESOURCE_MAPPING = new LinkedHashMap();
    String idName = "id";

    private static String driverClassName = "com.mysql.cj.jdbc.Driver";
    
    private static String DB_URL = "jdbc:mysql://172.20.248.220:3306/dmsUser?useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=convertToNull";
    private static String USER = "root";
    private static String PASSWORD = "le98i3nf";
    private static String systemId="-1";
    private static String appName="";

    public void parseXml() throws Exception {
        //Get the DOM Builder Factory
        DocumentBuilderFactory factory =
                DocumentBuilderFactory.newInstance();

        //Get the DOM Builder
        DocumentBuilder builder = factory.newDocumentBuilder();

        //Load and Parse the XML document
        //document contains the complete XML as a Tree.
        Document document =
                builder.parse(
                        ClassLoader.getSystemResourceAsStream(RESOURCE_FILE_PATH));

        //Iterating through the nodes and extracting the data.
        NodeList nodeList = document.getDocumentElement().getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node instanceof Element) {
            	
                //publicUrls,公共权限列表
                if (!PUtils.isEmpty(node.getNodeName()) && node.getNodeName().equals("systemId")) {
                    String parentId_publicUrls = "systemId";
                    NodeList childNodes = node.getChildNodes();
                    systemId=childNodes.item(0).getNodeValue();

                }
                
                //publicUrls,公共权限列表
                if (!PUtils.isEmpty(node.getNodeName()) && node.getNodeName().equals("appName")) {
                    String parentId_publicUrls = "appName";
                    NodeList childNodes = node.getChildNodes();
                    appName=childNodes.item(0).getNodeValue();

                }
                
                //publicUrls,公共权限列表
                if (!PUtils.isEmpty(node.getNodeName()) && node.getNodeName().equals("publicUrls")) {
                    String parentId_publicUrls = "publicUrls";
                    NodeList childNodes = node.getChildNodes();
                    int index=0;
                    for (int j = 0; j < childNodes.getLength(); j++) {
                        Node urlNode = childNodes.item(j);
                        if (urlNode instanceof Element) {
                            //url
                            if (!PUtils.isEmpty(urlNode.getNodeName()) && urlNode.getNodeName().equals("url")) {
                                NamedNodeMap nodeMap = urlNode.getAttributes();
                                LinkedHashMap<String, String> map = new LinkedHashMap<>();
                                for (int k = 0; k < nodeMap.getLength(); k++) {
                                    Node tmpNode = nodeMap.item(k);
                                    switch (tmpNode.getNodeName()) {
                                        case "resUrl": {
                                            index++;
                                            map.put("resUrl", tmpNode.getNodeValue());
                                            map.put("type", "-1");
                                            map.put("name", parentId_publicUrls + "_" + index);
                                            map.put("parentId", "-1");
                                            map.put("id", appName+"_"+(parentId_publicUrls + "_" + index).toUpperCase());
                                            map.put("description", "公共URL" + index);
                                            map.put("systemId", systemId);
                                            CACHE_MEMUS_SECURERESOURCE_MAPPING.put(map.get(idName), map);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                //folders
                
                if (!PUtils.isEmpty(node.getNodeName()) && node.getNodeName().equals("folders")) {
                    LinkedHashMap<String, String> map = parseNode(0,0,"root", node,false);
                    String parentId_folders = map.get(idName);
                    CACHE_MEMUS_SECURERESOURCE_MAPPING.put(map.get(idName), map);
                    NodeList childNodes = node.getChildNodes();
                    int menusItemOrder=0;
                    for (int j = 0; j < childNodes.getLength(); j++) {
                        Node menusNode = childNodes.item(j);
                        if (menusNode instanceof Element) {
                            //menus
                            if (!PUtils.isEmpty(menusNode.getNodeName()) && menusNode.getNodeName().equals("menus")) {
                                map = parseNode(1,menusItemOrder++,parentId_folders, menusNode,false);
                                String  parentId_menus=map.get(idName);
                                CACHE_MEMUS_SECURERESOURCE_MAPPING.put(map.get(idName), map);
                                NodeList menuNodes = menusNode.getChildNodes();
                                int menuItemOrder=0;
                                for (int k = 0; k < menuNodes.getLength(); k++) {
                                    //menu
                                    Node menuNode = menuNodes.item(k);
                                    if (menuNode instanceof Element) {
//                                        System.out.println(menuNode.getNodeName());
                                        String parentId =parentId_menus;
                                        if (!PUtils.isEmpty(menuNode.getNodeName()) && menuNode.getNodeName().equals("menu")) {
                                            map = parseNode(2,menuItemOrder++,parentId, menuNode,false);
                                            parentId = map.get(idName);
                                            CACHE_MEMUS_SECURERESOURCE_MAPPING.put(map.get(idName), map);
                                            NodeList buttonsNodes = menuNode.getChildNodes();
                                            for (int m = 0; m < buttonsNodes.getLength(); m++) {
                                                //buttons
                                                Node buttonsNode = buttonsNodes.item(m);
                                                if (buttonsNode instanceof Element) {
//                                                    System.out.println(buttonNode.getNodeName());
                                                    //buttons
                                                    if (!PUtils.isEmpty(buttonsNode.getNodeName()) && buttonsNode.getNodeName().equals("buttons")) {
                                                        NodeList buttonNodes = buttonsNode.getChildNodes();
                                                        int buttonItemOrder=0;
                                                        for (int n = 0; n < buttonNodes.getLength(); n++) {
                                                            //button
                                                            Node buttonNode = buttonNodes.item(n);
                                                            if (buttonNode instanceof Element) {
//                                                                System.out.println(buttonNode.getNodeName());
                                                                if (!PUtils.isEmpty(buttonNode.getNodeName()) && buttonNode.getNodeName().equals("button")) {
                                                                    String parentId_button = parentId;
                                                                    map = parseNode(3,buttonItemOrder++,parentId, buttonNode,true);
                                                                    parentId_button = map.get(idName);
                                                                    CACHE_MEMUS_SECURERESOURCE_MAPPING.put(parentId_button, map);
                                                                    NodeList urlsNodes = buttonNode.getChildNodes();
                                                                    for (int x = 0; x < urlsNodes.getLength(); x++) {
                                                                        //button
                                                                        Node urlsNode = urlsNodes.item(x);
                                                                        if (urlsNode instanceof Element) {
                                                                            switch (urlsNode.getNodeName()) {
                                                                                case "urls":
                                                                                    NodeList urlNodes = urlsNode.getChildNodes();
                                                                                    int urltemOrder=0;
                                                                                    for (int y = 0; y < urlNodes.getLength(); y++) {
                                                                                        //button
                                                                                        Node urlNode = urlNodes.item(y);
                                                                                        if (urlNode instanceof Element) {
                                                                                            map = parseNode(4,urltemOrder++,parentId_button, urlNode,true);
                                                                                            String parentId_url = map.get(idName);
                                                                                            CACHE_MEMUS_SECURERESOURCE_MAPPING.put(parentId_url, map);
                                                                                        }

                                                                                    }
                                                                                    break;
                                                                                case "fields":
                                                                                    NodeList fieldsNodes = urlsNode.getChildNodes();
                                                                                    int fieldsItemOrder=0;
                                                                                    for (int y = 0; y < fieldsNodes.getLength(); y++) {
                                                                                        //button
                                                                                        Node fieldsNode = fieldsNodes.item(y);
                                                                                        if (fieldsNode instanceof Element) {
                                                                                            map = parseNode(5,fieldsItemOrder++,parentId_button, fieldsNode,true,"2");
                                                                                            String parentId_url = map.get(idName);
                                                                                            CACHE_MEMUS_SECURERESOURCE_MAPPING.put(parentId_url, map);
                                                                                        }
                                                                                    }
                                                                                    break;
                                                                                default:
                                                                                    ;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public LinkedHashMap<String, String> parseNode(int menuLevel,int showOrder,String parentId, Node node, boolean isCombine,String type) {
        LinkedHashMap<String, String> result = parseNode(menuLevel,showOrder,parentId, node,isCombine);
        result.put("type", type);
        return result;
    }

    /**
     * 处理结点
     * @param parentId
     * @param node
     * @param isCombine 是否连接parentId加自身的id组成新的id，true为组合，false为不组合
     * @return
     */

    public LinkedHashMap<String, String> parseNode(int menuLevel,int showOrder,String parentId, Node node,boolean isCombine) {
        LinkedHashMap<String, String> result = new LinkedHashMap<>();
        result.put("menuLevel", String.valueOf(menuLevel));
        result.put("showOrder", String.valueOf(showOrder));
        result.put("parentId", parentId);
        if (node instanceof Element) {
            NamedNodeMap nodeMap = node.getAttributes();
            for (int i = 0; i < nodeMap.getLength(); i++) {
                Node tmpNode = nodeMap.item(i);
                switch (tmpNode.getNodeName()) {
                    case "name": {
                        result.put("name", tmpNode.getNodeValue());
                        break;
                    }
                    case "id": {
                        String id = tmpNode.getNodeValue();
                        String s =appName+"_";
                        String s3=s+s+s;
                        String s2=s+s;
                        if(isCombine) {
                            id = parentId + "_" + tmpNode.getNodeValue();
                         
                            id=id.replace(s3, s).replace(s2, s);
                            if (PUtils.isEmpty(parentId)) {
                                id = tmpNode.getNodeValue();
                            }
                        }
                        result.put("id", (appName+"_"+id).replace(s3, s).replace(s2, s));
                        break;
                    }
                    case "resUrl": {
                        result.put("resUrl", tmpNode.getNodeValue());
                        break;
                    }
                    case "description": {
                        String description=tmpNode.getNodeValue();
                        result.put("description", description);
                        break;
                    }
         
                    case "iconcss": {
                        result.put("iconcss", tmpNode.getNodeValue());
                        break;
                    }
                    case "tableField": {
                        result.put("tableField", tmpNode.getNodeValue());
                        break;
                    }
                    case "type": {
                        result.put("type", tmpNode.getNodeValue());
                        break;
                    }
                    case "hide": {
                        result.put("hide", tmpNode.getNodeValue());
                        break;
                    }
                }
            }
        }

        result.put("systemId", systemId);
        return result;
    }


    public void loadDBConnectionInfo() {
/*        try {
            final Properties properties = new Properties();
            final InputStream stream =
                    this.getClass().getResourceAsStream("/config.properties");
            if(stream==null){
                logger.error("不能找到数据库连接信息");
            }
            properties.load(stream);
            driverClassName = properties.getProperty("driverClassName");
            DB_URL = properties.getProperty("jdbc_url");
            USER = properties.getProperty("jdbc_username");
            PASSWORD = properties.getProperty("jdbc_password");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }*/

    }

    public int executeSQL(List<String> sqls) {
        int result=0;
        if (PUtils.isEmpty(DB_URL)) {
            loadDBConnectionInfo();
        }
        if (PUtils.isEmpty(DB_URL)) {
            logger.info("数据库信息获取错误");
           return result;
        }
//            String driverClassName = properties.getProperty("driverClassName");
//            String DB_URL = properties.getProperty("jdbc_url");
//            String USER = properties.getProperty("jdbc_username");
//            String PASSWORD = properties.getProperty("jdbc_password");

        Connection conn = null;
        Statement stmt = null;
        try {
            //STEP 2: Register JDBC driver
            Class.forName(driverClassName);

            //STEP 3: Open a connection
            System.out.println("Connecting to database...");
            conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
            conn.setAutoCommit(false);
            //STEP 4: Execute a query
            System.out.println("Executing statement...");
            stmt = conn.createStatement();
            for(String sql:sqls) {
            	System.out.println("------------------*** "+sql);
            	stmt.clearBatch();
                stmt.addBatch(sql);
                result= stmt.executeBatch().length;
            }
            //result= stmt.executeBatch().length;
            conn.commit();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            //Handle errors for JDBC
            se.printStackTrace();
        } catch (Exception e) {
            //Handle errors for Class.forName
            e.printStackTrace();
        } finally {
            //finally block used to close resources
            try {
                if (stmt != null)
                    stmt.close();
            } catch (SQLException se2) {
            }// nothing we can do
            try {
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }//end finally try
        }//end try
        return result;
    }

    public static void main(String[] args) throws Exception {
        logger.info("Running...");
        ResourceConfigImport resourceConfigImport = new ResourceConfigImport();
        List<String> sqls=new ArrayList<>();

        resourceConfigImport.parseXml();
        //删除已有的
        String sql="delete  from safe_function where systemId="+systemId+" ";
        sqls.add(sql);
        for (Map.Entry<String, LinkedHashMap<String, String>> entry : CACHE_MEMUS_SECURERESOURCE_MAPPING.entrySet()) {
            StringBuffer sb = new StringBuffer("INSERT INTO safe_function (name, menuLevel,showOrder,parentId, id, type, url,description,iconcss,hide,systemId) " + " VALUES(");
            Map<String, String> map = entry.getValue();
            if (map != null) {
                String name = map.get("name");
                if (!PUtils.isEmpty(name)) {
                    sb.append("'" + map.get("name") + "',");
                }

                String menuLevel = map.get("menuLevel");
                if (PUtils.isEmpty(menuLevel)) {
                    menuLevel= "0";
                }
                sb.append("'" + menuLevel + "',");

                String showOrder = map.get("showOrder");
                if (PUtils.isEmpty(showOrder)) {
                    showOrder= "0";
                }
                sb.append("'" + showOrder + "',");

                String parentId = map.get("parentId").toUpperCase();
                if (PUtils.isEmpty(parentId)) {
                    parentId = "";
                }
                sb.append("'" + parentId + "',");

                String id = map.get("id").toUpperCase();
                if (PUtils.isEmpty(id)) {
                    id = "";
                }
                sb.append("'" + id + "',");

                String type = map.get("type");
                if (PUtils.isEmpty(type)) {
                    type = "99";
                }
                sb.append("'" + type + "',");

                if ("2".equals(type)) {
                    //控制字段是否显示的数据库的字段名
                    String tableField = map.get("tableField");
                    if (PUtils.isEmpty(tableField)) {
                        tableField = "";
                    }
                    sb.append("'" + tableField + "',");
                } else {
                    //菜单项
                    String resUrl = map.get("resUrl");
                    if (PUtils.isEmpty(resUrl)) {
                        resUrl = "";
                    }
                    sb.append("'" + resUrl + "',");
                }

                String description = map.get("description");
                if (PUtils.isEmpty(description)) {
                    Map<String, String> parentMap =CACHE_MEMUS_SECURERESOURCE_MAPPING.get(parentId);
                    if(parentMap!=null) {
                        String parentparentId = parentMap.get("parentId");
                        //取上上一级的节点
                        Map<String, String> parentParentMap =CACHE_MEMUS_SECURERESOURCE_MAPPING.get(parentparentId);
                        if(parentParentMap!=null) {
                            //取上上一级的节点的name
                            description = parentParentMap.get("name")+"->"+parentMap.get("name");
                        }else {
                            //直接取父结点的name
                            description = parentMap.get("name");
                        }
                    }else {
                        description = "";
                    }
                }
                sb.append("'" + description + "',");

                String iconcss = map.get("iconcss");
                if (PUtils.isEmpty(iconcss)) {
                    iconcss = "";
                }
                sb.append("'" + iconcss + "',");

                String hide = map.get("hide");
                if (PUtils.isEmpty(hide)) {
                    hide = "0";
                }
                sb.append("'" + hide + "',");
                
                String systemId = map.get("systemId");
                if (PUtils.isEmpty(systemId)) {
                	systemId = "-1";
                }
                sb.append("'" + systemId + "'");
                

                sb.append(")");
            }
            System.out.println(sb.toString());
            sqls.add(sb.toString());
            System.out.println("-------------------------------------------------------------------------------------------------------");
        }
        //删除管理员
        sql="delete  from safe_role_function where roleId=1 AND functionId NOT LIKE 'lineID_%'";
        sqls.add(sql);
        sql="INSERT INTO safe_role_function(roleId, functionId) select 1,id from safe_function ";
        sqls.add(sql);
        int count=  resourceConfigImport.executeSQL(sqls);
        sqls.clear();
        
        
        //删除浏览员
        sql="delete  from safe_role_function where roleId=2 AND functionId NOT LIKE 'lineID_%'";
        sqls.add(sql);
        sql="INSERT INTO safe_role_function(roleId, functionId) select 2,id from safe_function t1 where t1.url like 'GET://%' ";
        sqls.add(sql);
        int count1=  resourceConfigImport.executeSQL(sqls);
        sqls.clear();
        
        
        sql="delete from safe_role where id=1";
        sqls.add(sql);
        sql="INSERT INTO `safe_role` (`id`, `name`, `status`) VALUES ('1', '超级管理员', '1')";
        sqls.add(sql);
        
        sql="delete from safe_role where id=2";
        sqls.add(sql);
        sql="INSERT INTO `safe_role` (`id`, `name`, `status`) VALUES ('2', '浏览员', '1')";
        sqls.add(sql);
        
        resourceConfigImport.executeSQL(sqls);
        logger.info("执行成功。"+count+"|"+count1);

    }


}
